package org.flowcircuit.utils


object CallbackList {

  def apply[T]( initialList : List[T], onAdded : T => Unit, onRemoved : T => Unit ) : CallbackList[T] = new CallbackList[T](initialList, onAdded, onRemoved)
  def apply[T]( initialList : List[T], onAdded : T => Unit ) : CallbackList[T] = new CallbackList[T](initialList, onAdded, null)
  def apply[T]( initialList : List[T] ) : CallbackList[T] = new CallbackList[T](initialList, null, null)

  def apply[T]( onAdded : T => Unit, onRemoved : T => Unit ) : CallbackList[T] = new CallbackList[T](Nil, onAdded, onRemoved)
  def apply[T]( onAdded : T => Unit ) : CallbackList[T] = new CallbackList[T](Nil, onAdded, null)
  def apply[T]() : CallbackList[T] = new CallbackList[T](Nil, null, null) 

  implicit def callbackList2List[T](callbackList : CallbackList[T]) : List[T] = callbackList.list
}



/**
 * A list with callback functions that get called when elements are added or removed from the list.
 * 
 * @author Hans Haggstrom
 */
class CallbackList[T]( initialList : List[T], onAdded : T => Unit, onRemoved : T => Unit ) {

  private var _list : List[T] = initialList

  def list = _list

  def clear() {
    _list foreach onRemoved 
    _list = Nil
  }

  def add( element : T ) {
    _list = _list ::: List( element )
    if (onAdded != null) onAdded( element )
  }

  def addIfNotFound( element : T ) {
    if (!has(element)) add( element)
  }

  def remove( element : T ) {
    if (has( element )) {
      _list = _list.remove( _ == element )
      if (onRemoved != null) onRemoved( element )
    }
  }

  def addAll( elements : Iterator[T] ) = elements foreach add
  def removeAll( elements : Iterator[T] ) = elements foreach remove

  def has( element : T ) = _list.contains( element )
  def contains( element : T ) = has( element )

}